package com.ruoyi.web.service.impl;

import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.framework.web.exception.TadpoleException;
import com.ruoyi.web.domain.SmsSendDetail;
import com.ruoyi.web.domain.SmsSendRecord;
import com.ruoyi.web.excel.SmsSendRecordExcel;
import com.ruoyi.web.mapper.SmsSendDetailMapper;
import com.ruoyi.web.mapper.SmsSendRecordMapper;
import com.ruoyi.web.service.ISmsSendRecordService;
import com.ruoyi.web.utils.CommonUtil;
import com.ruoyi.web.utils.MysqlUtil;
import com.ruoyi.web.utils.twilio.utils.TwilioSender;
import com.twilio.rest.api.v2010.account.Message;
import lombok.AllArgsConstructor;
import org.apache.logging.log4j.util.Strings;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 短信发送记录Service业务层处理
 *
 * @date 2023-03-28
 */
@Service
@AllArgsConstructor
public class SmsSendRecordServiceImpl implements ISmsSendRecordService {
    private final SmsSendRecordMapper smsSendRecordMapper;
    private final SmsSendDetailMapper smsSendDetailMapper;
    private final CommonUtil commonUtil;
    private final MysqlUtil mysqlUtil;
    private final TwilioSender twilioSender;

    /**
     * 查询短信发送记录
     *
     * @param id 短信发送记录主键
     * @return 短信发送记录
     */
    @Override
    public SmsSendRecord selectSmsSendRecordById(Long id) {
        return smsSendRecordMapper.selectSmsSendRecordById(id);
    }

    /**
     * 查询短信发送记录列表
     *
     * @param smsSendRecord 短信发送记录
     * @return 短信发送记录
     */
    @Override
    public List<SmsSendRecord> selectSmsSendRecordList(SmsSendRecord smsSendRecord) {
        return smsSendRecordMapper.selectSmsSendRecordList(smsSendRecord);
    }

    /**
     * 新增短信发送记录
     *
     * @param smsSendRecord 短信发送记录
     * @return 结果
     */
    @Override
    public int insertSmsSendRecord(SmsSendRecord smsSendRecord) {
        smsSendRecord.setCreateTime(DateUtils.getNowDate());
        return smsSendRecordMapper.insertSmsSendRecord(smsSendRecord);
    }

    /**
     * 修改短信发送记录
     *
     * @param smsSendRecord 短信发送记录
     * @return 结果
     */
    @Override
    public int updateSmsSendRecord(SmsSendRecord smsSendRecord) {
        smsSendRecord.setUpdateTime(DateUtils.getNowDate());
        return smsSendRecordMapper.updateSmsSendRecord(smsSendRecord);
    }

    /**
     * 批量删除短信发送记录
     *
     * @param ids 需要删除的短信发送记录主键
     * @return 结果
     */
    @Override
    public int deleteSmsSendRecordByIds(Long[] ids) {
        return smsSendRecordMapper.deleteSmsSendRecordByIds(ids);
    }

    /**
     * 删除短信发送记录信息
     *
     * @param id 短信发送记录主键
     * @return 结果
     */
    @Override
    public int deleteSmsSendRecordById(Long id) {
        return smsSendRecordMapper.deleteSmsSendRecordById(id);
    }

    /**
     * 根据excel文件群发消息
     *
     * @param list 文件
     * @param user 用户
     * @since 2023/3/28 17:03
     */
    @Async
    @Override
    public void add(List<SmsSendRecordExcel> list, SysUser user) {
        // 新增发送记录
        SmsSendRecord record = new SmsSendRecord();
        record.setNum(list.size());
        record.setSuccessNum(0);
        record.setMessage(list.get(0).getContent());
        commonUtil.initCreateAbout(record, user);
        if (smsSendRecordMapper.insertSmsSendRecord(record) != 1) {
            throw new TadpoleException();
        }

        // 发送短信，生成明细记录
        list.forEach(i -> {
            if (Strings.isBlank(i.getAreaCode()) || Strings.isBlank(i.getPhone())) {
                return;
            }

            SmsSendDetail detail = new SmsSendDetail();
            detail.setRecordId(record.getId());
            detail.setPhoneTo(i.getAreaCode() + i.getPhone());
            commonUtil.initCreateAbout(detail, user);

            try {
                Message res = twilioSender.sendSms(detail.getPhoneTo(), record.getMessage());
                detail.setSmsId(res.getSid());
                detail.setStatus(res.getStatus().toString());
                if (!Message.Status.ACCEPTED.equals(res.getStatus())) {
                    detail.setRemark(res.getErrorCode() + " " + res.getErrorMessage());
                }

            } catch (Throwable e) {
                e.printStackTrace();
                detail.setStatus("requestFail");
                detail.setRemark(e.getMessage());
            }

            try {
                // 开启本地事务
                mysqlUtil.startLocalTx();
                if (smsSendDetailMapper.insertSmsSendDetail(detail) != 1) {
                    throw new TadpoleException();
                }
                // 提交本地事务
                mysqlUtil.commitLocalTx();
            } catch (Throwable e) {
                mysqlUtil.rollbackLocalTx();
            }
        });
    }
}
